import {
  call, put, all, takeLatest, select
} from 'redux-saga/effects'
import api from '@API'
import {
  BOT_START_JOURNEY,
  BOT_INPUT, BOT_START_EVALUATION, BOT_ANSWER_QUESTION
} from '@ACTIONS/smartAssistant'
import { OUT_PUT_ENUM, SCENARIO_ENUM, TRIGGER_EVENT_ENUM } from '@CONSTANTS/smartAssistant'
import {
  getAssistantDetail,
  getCurrentEvaluation,
  getEvaluationMessages,
  getEvaluationQuestions
} from '@SAGAS/dataSelect'
import {
  SmartAssistantBotInputActionITF,
  SmartAssistantQuestionActionITF,
  SmartAssistantStartEvaluationActionITF, SmartAssistantStartJourneyActionITF
} from '@REDUXITF/smartAssistant'
import { QuestionITF } from '@INTERFACES/Survey'
import { AssistantMsgITF } from '@INTERFACES/SmartAssistant'
import { getTagIds } from '@UTILS/common'

const startJourney = function* startJourney(action: SmartAssistantStartJourneyActionITF) {
  try {
    const { scenario } = action
    const result = yield call(api.startJourney, { Scenario: scenario || SCENARIO_ENUM.UserInitiateBot })
    const { JourneyId, OutputType, EntityId } = result
    if (OutputType === OUT_PUT_ENUM.Text) {
      yield put({
        type: BOT_INPUT.REQUEST,
        data: {
          addSendMsg: false,
          addReturnMsg: true,
          Text: '',
          payload: {
            JourneyId,
            EntityId,
            TriggerEvent: TRIGGER_EVENT_ENUM.SkipSurveyNew
          }
        }
      })
    }
    yield put({ type: BOT_START_JOURNEY.SUCCESS, data: result })
  } catch (error) {
    yield put({ type: BOT_START_JOURNEY.FAILURE, error })
  }
}
const botInput = function* botInput(action: SmartAssistantBotInputActionITF) {
  try {
    const { data: { payload, addReturnMsg } = {}, } = action
    const result = yield call(api.botInput, { ...payload })
    if (!addReturnMsg) return
    yield put({ type: BOT_INPUT.SUCCESS, data: { ...result, SearchText: payload?.Text } })
  } catch (error) {
    yield put({ type: BOT_INPUT.FAILURE, error })
  }
}
const startEvaluation = function* startEvaluation(action: SmartAssistantStartEvaluationActionITF) {
  try {
    const { data: { p8Id } } = action
    const params = { TemplateId: p8Id }
    const assistantDetail = yield select(getAssistantDetail)
    const { JourneyId } = assistantDetail || {}
    JourneyId && (Object.assign(params, { BotJourneyId: JourneyId }))
    const result = yield call(api.startSurvey, params)
    yield put({ type: BOT_START_EVALUATION.SUCCESS, result })
  } catch (error) {
    yield put({ type: BOT_START_EVALUATION.FAILURE, error })
  }
}
const submitEvaluation = function* submitEvaluation(action: SmartAssistantQuestionActionITF) {
  try {
    const { message, choice } = action
    const questions = yield select(getEvaluationQuestions)
    const questionIndex = questions.findIndex((item: QuestionITF) => item.Code === message.EvaluationChoice?.Code)
    if (questionIndex !== questions.length - 1) return

    const { JourneyId } = yield select(getAssistantDetail)
    const currentEvaluation = yield select(getCurrentEvaluation)
    const evaluationMessages = yield select(getEvaluationMessages)
    const answers = []
    evaluationMessages.forEach((item: AssistantMsgITF) => {
      const { EvaluationAnswer, isSelf, uuId } = item
      if (uuId === message.uuId && isSelf && EvaluationAnswer) {
        const { AnswerChoice, Code } = EvaluationAnswer
        answers.push({ Code, AnswerChoice: AnswerChoice.Label })
      }
    })
    answers.push({ Code: message.EvaluationChoice?.Code, AnswerChoice: choice.Label })
    const result = yield call(api.submitSurvey, { SurveyId: currentEvaluation.p8Id, QnA: answers })
    const { Tags } = result
    const dTagIds = getTagIds(Tags)
    let addReturnMsg = true
    let addSendMsg = false
    if (dTagIds.length > 0) {
      const { Templates } = yield call(api.getTemplatesByTagIds, { tIds: JSON.stringify(dTagIds) })
      if (Array.isArray(Templates) && Templates?.length > 0) {
        addReturnMsg = false
        addSendMsg = false
        result.Templates = Templates
      }
    }
    yield put({ type: BOT_ANSWER_QUESTION.SUCCESS, result })
    yield put({ type: BOT_INPUT.REQUEST,
      data: {
        addReturnMsg,
        addSendMsg,
        payload: {
          JourneyId,
          TriggerEvent: TRIGGER_EVENT_ENUM.SubmittedSurveyNew
        }
      } })
  } catch (error) {
    yield put({ type: BOT_ANSWER_QUESTION.FAILURE, error })
  }
}

export default function* rootSaga(): Generator {
  yield all([
    takeLatest(BOT_START_JOURNEY.REQUEST, startJourney),
    takeLatest(BOT_INPUT.REQUEST, botInput),
    takeLatest(BOT_START_EVALUATION.REQUEST, startEvaluation),
    takeLatest(BOT_ANSWER_QUESTION.REQUEST, submitEvaluation),
  ]);
}

